/**
 * Worker 进程主程序
 *
 * 运行在独立进程中，负责执行具体的预约任务
 * 与主进程通过 IPC 通信
 */

import type { AppointmentManagement } from '@shared/types/'
import type { BookingOptions } from '../strategy'
import { loadConfig } from '../../config/index'
import { getLogger, setupLogger } from '../../logger/index'
import { getUnifiedBookingService } from '../booking-service'

// 标记为 Worker 模式
process.env.WORKER_MODE = 'true'

// 初始化配置和日志（Worker 进程需要独立初始化）
let logger: ReturnType<typeof getLogger>
let configInitialized = false

async function initializeWorker() {
  if (configInitialized)
    return

  try {
    console.log(`[Worker ${process.pid}] 开始初始化...`)

    // 加载配置
    await loadConfig()
    console.log(`[Worker ${process.pid}] 配置加载完成`)

    // 初始化日志
    await setupLogger()
    console.log(`[Worker ${process.pid}] 日志初始化完成`)

    // 获取 logger
    logger = getLogger()
    configInitialized = true

    console.log(`[Worker ${process.pid}] 初始化完成`)
  }
  catch (error) {
    console.error(`[Worker ${process.pid}] 初始化失败:`, error)
    console.error(`[Worker ${process.pid}] 错误堆栈:`, error instanceof Error ? error.stack : '')
    process.exit(1)
  }
}

// 延迟初始化，避免在模块加载时执行
initializeWorker().catch((err) => {
  console.error('[Worker] 初始化错误:', err)
  console.error('[Worker] 错误堆栈:', err.stack)
  process.exit(1)
})

/**
 * 任务消息接口
 */
interface TaskMessage {
  type: 'task'
  taskId: string
  payload: {
    mode: 'playwright' | 'request'
    appointment: AppointmentManagement
    options?: BookingOptions
  }
}

/**
 * 控制消息接口
 */
interface ControlMessage {
  type: 'stop' | 'restart' | 'ping'
}

/**
 * 发送就绪信号给主进程（等待初始化完成）
 */
async function sendReady() {
  try {
    console.log(`[Worker ${process.pid}] 准备发送就绪信号...`)

    await initializeWorker()

    if (process.send) {
      process.send({ type: 'ready' })
      console.log(`[Worker ${process.pid}] 就绪信号已发送`)
      logger.debug('Worker 进程已就绪', { pid: process.pid })
    }
    else {
      console.error(`[Worker ${process.pid}] process.send 不可用`)
      logger.error('Worker 进程无法发送消息（process.send 不可用）')
      process.exit(1)
    }
  }
  catch (error) {
    console.error(`[Worker ${process.pid}] sendReady 失败:`, error)
    console.error(`[Worker ${process.pid}] 错误堆栈:`, error instanceof Error ? error.stack : '')
    process.exit(1)
  }
}

// 延迟发送就绪信号，确保初始化完成
sendReady().catch((err) => {
  console.error(`[Worker ${process.pid}] 就绪信号发送失败:`, err)
  console.error(`[Worker ${process.pid}] 错误堆栈:`, err instanceof Error ? err.stack : '')
  process.exit(1)
})

/**
 * 监听主进程消息
 */
process.on('message', async (message: TaskMessage | ControlMessage) => {
  try {
    // 确保已初始化
    await initializeWorker()

    if (message.type === 'task') {
      await handleTask(message as TaskMessage)
    }
    else if (message.type === 'stop') {
      logger.info('收到停止信号，准备退出', { pid: process.pid })
      process.exit(0)
    }
    else if (message.type === 'ping') {
      // 心跳响应
      if (process.send) {
        process.send({ type: 'pong' })
      }
    }
    else if (message.type === 'restart') {
      logger.info('收到重启信号', { pid: process.pid })
      process.exit(0) // 退出后由主进程重启
    }
  }
  catch (error) {
    const err = error instanceof Error ? error : new Error(String(error))
    const errorMsg = err.message || String(error)
    const errorStack = err.stack

    // 如果 logger 未初始化，使用 console
    if (logger) {
      logger.error('处理消息时发生错误', {
        pid: process.pid,
        error: errorMsg,
        stack: errorStack,
      })
    }
    else {
      console.error('处理消息时发生错误:', errorMsg, errorStack)
    }

    if (process.send) {
      process.send({
        type: 'error',
        error: errorMsg,
        stack: errorStack,
      })
    }
  }
})

/**
 * 处理预约任务
 */
async function handleTask(message: TaskMessage): Promise<void> {
  const { taskId, payload } = message

  logger.debug('开始执行任务', { taskId, mode: payload.mode, pid: process.pid })

  try {
    const bookingService = getUnifiedBookingService()

    // 进度回调
    const progressCallback = (progress: { progress: number, step: string }) => {
      if (process.send) {
        process.send({
          type: 'progress',
          taskId,
          progress: progress.progress,
          step: progress.step,
          timestamp: Date.now(),
        })
      }
    }

    // 执行预约
    const result = await bookingService.bookWith(
      payload.mode,
      payload.appointment,
      {
        ...payload.options,
        onProgress: progressCallback,
      },
    )

    logger.debug('任务执行完成', {
      taskId,
      success: result.success,
      pid: process.pid,
    })

    // 发送结果
    if (process.send) {
      process.send({
        type: 'result',
        taskId,
        success: result.success,
        data: result,
        error: result.error,
      })
    }
  }
  catch (error) {
    const err = error instanceof Error ? error : new Error(String(error))
    logger.error('任务执行失败', {
      taskId,
      error: err.message,
      stack: err.stack,
      pid: process.pid,
    })

    if (process.send) {
      process.send({
        type: 'error',
        taskId,
        error: err.message,
        stack: err.stack,
      })
    }
  }
}

/**
 * 错误处理：捕获未处理的异常
 */
process.on('uncaughtException', (error) => {
  const errorMsg = error.message || String(error)
  const errorStack = error.stack

  if (logger) {
    logger.error('Worker 进程未捕获异常', {
      pid: process.pid,
      error: errorMsg,
      stack: errorStack,
    })
  }
  else {
    console.error('Worker 进程未捕获异常:', errorMsg, errorStack)
  }

  if (process.send) {
    process.send({
      type: 'error',
      error: errorMsg,
      stack: errorStack,
    })
  }

  // 延迟退出，给主进程时间接收错误消息
  setTimeout(() => {
    process.exit(1)
  }, 1000)
})

/**
 * 错误处理：捕获未处理的 Promise 拒绝
 */
process.on('unhandledRejection', (reason) => {
  const reasonStr = String(reason)

  if (logger) {
    logger.error('Worker 进程未处理的 Promise 拒绝', {
      pid: process.pid,
      reason: reasonStr,
    })
  }
  else {
    console.error('Worker 进程未处理的 Promise 拒绝:', reasonStr)
  }

  if (process.send) {
    process.send({
      type: 'error',
      error: reasonStr,
    })
  }
})
